import { WebXRDefaultExperience } from "@babylonjs/core/XR/webXRDefaultExperience";
import { Scene } from "@babylonjs/core/scene";
import { WebXRControllerMovement, WebXRControllerMovementRegistrationConfiguration } from "@babylonjs/core/XR/features/WebXRControllerMovement";
import { WebXRFeatureName } from "@babylonjs/core/XR/webXRFeaturesManager";
import { WebXRInput } from "@babylonjs/core/XR/webXRInput";
import { WebXRControllerComponent } from "@babylonjs/core/XR/motionController/webXRControllerComponent";
import '@babylonjs/core/XR/features/WebXRControllerMovement';


/**
 * 控制器连续移动参数对象
 * @param xrInput xr输入
 * @param movementEnabled 启用控制器连续移动
 * @param movementOrientationFollowsViewerPose 运动方向跟随视角
 * @param movementSpeed 移动速度
 * @param movementThreshold 移动阈值
 * @param rotationEnabled 启用旋转
 * @param rotationSpeed 旋转速度
 * @param rotationThreshold 旋转阈值
 * @param customRegistrationConfigurations 自定义配置
 */
interface IVRMotionMovementOptions {
    xrInput?: WebXRInput,
    movementEnabled?: boolean,
    movementOrientationFollowsViewerPose?: boolean,
    movementSpeed?: boolean,
    movementThreshold?: number,
    rotationEnabled?: boolean,
    rotationSpeed?: number,
    rotationThreshold?: number,
    customRegistrationConfigurations?: WebXRControllerMovementRegistrationConfiguration[],
}


/**
 * 控制器连续移动
 * @param xr xr实例
 * @param scene 所在场景
 * @param options 参数对象
 */
class VRMotionMovement {

    /**
     * 原生控制器移动组件
     */
    public movement: WebXRControllerMovement;

    constructor(xr: WebXRDefaultExperience, scene: Scene, options?: IVRMotionMovementOptions) {
        const ops = options || {};
        const featureManager = xr.baseExperience.featuresManager;
        ops.xrInput = ops.xrInput || xr.input;
        this.movement = featureManager.enableFeature(WebXRFeatureName.MOVEMENT, "latest", ops) as WebXRControllerMovement;
    }

}

/**
 * 交换惯用手（左手默认行为变为右手，右手默认行为变为左手）
 * 右手前后左右旋转
 * 左手前后左右移动
 */
const SWAPPED_HANDEDNESS_CONFIGURATION: WebXRControllerMovementRegistrationConfiguration[] = [
    {
        allowedComponentTypes: [WebXRControllerComponent.THUMBSTICK_TYPE, WebXRControllerComponent.TOUCHPAD_TYPE],
        forceHandedness: 'right',
        axisChangedHandler: (axes, movementState, featureContext, xrInput) => {
            movementState.rotateX = Math.abs(axes.x) > featureContext.rotationThreshold ? axes.x : 0;
            movementState.rotateY = Math.abs(axes.y) > featureContext.rotationThreshold ? axes.y : 0;
        }
    },
    {
        allowedComponentTypes: [WebXRControllerComponent.THUMBSTICK_TYPE, WebXRControllerComponent.TOUCHPAD_TYPE],
        forceHandedness: 'left',
        axisChangedHandler: (axes, movementState, featureContext, xrInput) => {
            movementState.moveX = Math.abs(axes.x) > featureContext.movementThreshold ? axes.x : 0;
            movementState.moveY = Math.abs(axes.y) > featureContext.movementThreshold ? axes.y : 0;
        },
    }
];

/**
 * 左右手功能相同
 * 前后移动，左右旋转
 */
const SEPARATE_X_ROTATE_HANDEDNESS_CONFIGURATION: WebXRControllerMovementRegistrationConfiguration[] = [
    {
        allowedComponentTypes: [WebXRControllerComponent.THUMBSTICK_TYPE, WebXRControllerComponent.TOUCHPAD_TYPE],
        forceHandedness: 'right',
        axisChangedHandler: (axes, movementState, featureContext, xrInput) => {
            movementState.rotateX = Math.abs(axes.x) > featureContext.rotationThreshold ? axes.x : 0;
            movementState.moveY = Math.abs(axes.y) > featureContext.movementThreshold ? axes.y : 0;
        }
    },
    {
        allowedComponentTypes: [WebXRControllerComponent.THUMBSTICK_TYPE, WebXRControllerComponent.TOUCHPAD_TYPE],
        forceHandedness: 'left',
        axisChangedHandler: (axes, movementState, featureContext, xrInput) => {
            movementState.rotateX = Math.abs(axes.x) > featureContext.rotationThreshold ? axes.x : 0;
            movementState.moveY = Math.abs(axes.y) > featureContext.movementThreshold ? axes.y : 0;
        },
    }
];

/**
 * 左右手功能相同
 * 前后无功能，左右旋转
 */
const SEPARATE_ONLY_ROTATE_HANDEDNESS_CONFIGURATION: WebXRControllerMovementRegistrationConfiguration[] = [
    {
        allowedComponentTypes: [WebXRControllerComponent.THUMBSTICK_TYPE, WebXRControllerComponent.TOUCHPAD_TYPE],
        forceHandedness: 'right',
        axisChangedHandler: (axes, movementState, featureContext, xrInput) => {
            movementState.rotateX = Math.abs(axes.x) > featureContext.rotationThreshold ? axes.x : 0;
        }
    },
    {
        allowedComponentTypes: [WebXRControllerComponent.THUMBSTICK_TYPE, WebXRControllerComponent.TOUCHPAD_TYPE],
        forceHandedness: 'left',
        axisChangedHandler: (axes, movementState, featureContext, xrInput) => {
            movementState.rotateX = Math.abs(axes.x) > featureContext.rotationThreshold ? axes.x : 0;
        },
    }
];

/**
 * 左右手功能相同
 * 前后左右移动
 */
const SEPARATE_NO_ROTATE_HANDEDNESS_CONFIGURATION: WebXRControllerMovementRegistrationConfiguration[] = [
    {
        allowedComponentTypes: [WebXRControllerComponent.THUMBSTICK_TYPE, WebXRControllerComponent.TOUCHPAD_TYPE],
        forceHandedness: 'right',
        axisChangedHandler: (axes, movementState, featureContext, xrInput) => {
            movementState.moveX = Math.abs(axes.x) > featureContext.movementThreshold ? axes.x : 0;
            movementState.moveY = Math.abs(axes.y) > featureContext.movementThreshold ? axes.y : 0;
        }
    },
    {
        allowedComponentTypes: [WebXRControllerComponent.THUMBSTICK_TYPE, WebXRControllerComponent.TOUCHPAD_TYPE],
        forceHandedness: 'left',
        axisChangedHandler: (axes, movementState, featureContext, xrInput) => {
            movementState.moveX = Math.abs(axes.x) > featureContext.movementThreshold ? axes.x : 0;
            movementState.moveY = Math.abs(axes.y) > featureContext.movementThreshold ? axes.y : 0;
        },
    }
];

/**
 * 右手前后左右移动
 * 左手前后移动，左右旋转
 */
const SEPARATE_LEFT_X_ROTATE_HANDEDNESS_CONFIGURATION: WebXRControllerMovementRegistrationConfiguration[] = [
    {
        allowedComponentTypes: [WebXRControllerComponent.THUMBSTICK_TYPE, WebXRControllerComponent.TOUCHPAD_TYPE],
        forceHandedness: 'right',
        axisChangedHandler: (axes, movementState, featureContext, xrInput) => {
            movementState.moveX = Math.abs(axes.x) > featureContext.movementThreshold ? axes.x : 0;
            movementState.moveY = Math.abs(axes.y) > featureContext.movementThreshold ? axes.y : 0;
        }
    },
    {
        allowedComponentTypes: [WebXRControllerComponent.THUMBSTICK_TYPE, WebXRControllerComponent.TOUCHPAD_TYPE],
        forceHandedness: 'left',
        axisChangedHandler: (axes, movementState, featureContext, xrInput) => {
            movementState.rotateX = Math.abs(axes.x) > featureContext.rotationThreshold ? axes.x : 0;
            movementState.moveY = Math.abs(axes.y) > featureContext.movementThreshold ? axes.y : 0;
        },
    }
];

/**
 * 右手前后移动，左右旋转
 * 左手前后左右移动
 */
const SEPARATE_RIGHT_X_ROTATE_HANDEDNESS_CONFIGURATION: WebXRControllerMovementRegistrationConfiguration[] = [
    {
        allowedComponentTypes: [WebXRControllerComponent.THUMBSTICK_TYPE, WebXRControllerComponent.TOUCHPAD_TYPE],
        forceHandedness: 'right',
        axisChangedHandler: (axes, movementState, featureContext, xrInput) => {
            movementState.rotateX = Math.abs(axes.x) > featureContext.rotationThreshold ? axes.x : 0;
            movementState.moveY = Math.abs(axes.y) > featureContext.movementThreshold ? axes.y : 0;
        }
    },
    {
        allowedComponentTypes: [WebXRControllerComponent.THUMBSTICK_TYPE, WebXRControllerComponent.TOUCHPAD_TYPE],
        forceHandedness: 'left',
        axisChangedHandler: (axes, movementState, featureContext, xrInput) => {
            movementState.moveX = Math.abs(axes.x) > featureContext.movementThreshold ? axes.x : 0;
            movementState.moveY = Math.abs(axes.y) > featureContext.movementThreshold ? axes.y : 0;
        },
    }
];


export {
    VRMotionMovement,
    SWAPPED_HANDEDNESS_CONFIGURATION,
    SEPARATE_NO_ROTATE_HANDEDNESS_CONFIGURATION,
    SEPARATE_X_ROTATE_HANDEDNESS_CONFIGURATION,
    SEPARATE_LEFT_X_ROTATE_HANDEDNESS_CONFIGURATION,
    SEPARATE_RIGHT_X_ROTATE_HANDEDNESS_CONFIGURATION,
    SEPARATE_ONLY_ROTATE_HANDEDNESS_CONFIGURATION,
};
export type { IVRMotionMovementOptions };